package com.bugsnag.ohos;

import com.bugsnag.ohos.internal.ImmutableConfig;

import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Tracks whether the app is currently in its launch period. This creates a timer of
 * configuration.launchDurationMillis, after which which the launch period is considered
 * complete. If this value is zero, then the user must manually call markLaunchCompleted().
 *
 * @since 2021-07-02
 */
public class LaunchCrashTracker extends BaseObservable {
    private ScheduledThreadPoolExecutor executor;

    private AtomicBoolean launching = new AtomicBoolean(true);
    private Logger logger;

    /**
     * constructor
     *
     * @param config
     */
    public LaunchCrashTracker(ImmutableConfig config) {
        this(config, new ScheduledThreadPoolExecutor(1));
    }

    /**
     * constructor
     *
     * @param config
     * @param executor
     */
    public LaunchCrashTracker(ImmutableConfig config, ScheduledThreadPoolExecutor executor) {
        logger = config.getLogger();
        this.executor = executor;
        long delay = config.getLaunchDurationMillis();
        if (delay > 0) {
            executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
            try {
                executor.schedule(() -> markLaunchCompleted(), delay, TimeUnit.MILLISECONDS);
            } catch (RejectedExecutionException exc) {
                logger.w("Failed to schedule timer for LaunchCrashTracker", exc);
            }
        }
    }

    void markLaunchCompleted() {
        executor.shutdown();
        launching.set(false);
        updateState(new StateEvent.UpdateIsLaunching(false));
        logger.d("App launch period marked as complete");
    }

    public boolean isLaunching() {
        return launching.get();
    }
}
